qt 从零开始搭建插件框架

您所在的位置:网站首页 lua 插件框架 qt 从零开始搭建插件框架

qt 从零开始搭建插件框架

2024-01-07 18:06| 来源: 网络整理| 查看: 265

系统设计 搭建插件框架的好处

分析

至少分为以下几个模块

需要至少一个界面插件,用于展示界面需要一些功能插件,为界面提供所需功能,例如FTP功能,网络服务,数据库等等需要一个插件用于管理其他插件,插件间的通信,维护等等需要一个启动程序作为入口 流程 mainApp项目作为启动整个程序的入口,生成传统意义上的exe文件,点击它启动软件启动之后,需要加载管理插件的插件项目(命名为QtPluginFramework)QtPluginFramework加载各个插件:包括界面插件,功能插件等等界面显示,用户互动产生命令调用功能插件用户退出界面,QtPluginFramework卸载各个插件mainApp退出 QtPluginFramework项目 分析

插件式开发的好处在于,每个人可以独立的负责某个小的模块,这个模块还可以给其他的项目组用,而且很方便添加其他功能。所以QtPluginFramework项目的作用就是

定义一个公共接口QtPluginInterface,所有的插件都必须实现这个接口加载和卸载单个插件的功能,定义QtPlugin类集中管理所有插件的功能,定义QtPluginManage类插件间的通信功能,定义QtEvents类最后定义QtPluginFramework类,集成以上所有功能 实现 QtPluginInterface #ifndef QtPluginInterface_H_ #define QtPluginInterface_H_ class CPluginFramework; class QtPluginInterface { public: virtual ~QtPluginInterface(){} // virtual void Start(QtPluginFramework* pPluginFramework) = 0; // virtual void Stop(QtPluginFramework* pPluginFramework) = 0; }; Q_DECLARE_INTERFACE(QtPluginInterface, "Plugin.QtPluginInterface") #endif QtPlugin

加载和卸载单个插件

在这里插入代码片 参考文献

参考文献1 参考 qt 官方示例 Echo Plugin Example 怎样用 Qt 写个插件? 在项目中创建并使用自定义Qt插件【VS+Qt项目开发系列】(六) 使用ctkPluginFramework插件系统构建项目实战 ** ctk github CTK框架使用简明教程 QT——插件的创建和使用

实战 新建库项目

在这里插入图片描述 选择chose进入下一下页面,类型选择Qt Plugin,输入一个名称

新建如下文件 在这里插入图片描述

首先需要一个虚接口 echointerface.h,在插件工程和要运行插件的工程中都要使用

#ifndef ECHOINTERFACE_H #define ECHOINTERFACE_H #include #include //! [0] class EchoInterface { public: virtual ~EchoInterface() = default; virtual QString echo(const QString &message) = 0; }; QT_BEGIN_NAMESPACE #define EchoInterface_iid "org.qt-project.Qt.Examples.EchoInterface" Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid) QT_END_NAMESPACE //! [0] #endif

Q_DECLARE_INTERFACE() 向 Qt 元对象系统注册一下我写的这个接口。 该宏的第一个参数是接口类的名字,第二个参数是 iid(相当于一个身份证信息,可以随便写个字符串)。

至此,我的程序给外界提供了个公共接口,并且为了 Qt 编程方便还向元对象系统注册了一下。以后所有的插件都通过这个接口来扩展 app 的功能,当然也可以写更多的接口供外界调用。

接下来是写插件,要继承这个接口 echoplugin.h

#ifndef ECHOPLUGIN_H #define ECHOPLUGIN_H #include #include #include "echointerface.h" //! [0] class EchoPlugin : public QObject, EchoInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.EchoInterface" FILE "MyQtPlugin.json") Q_INTERFACES(EchoInterface) public: QString echo(const QString &message) override; }; //! [0] #endif

echoplugin.cpp

#include "echoplugin.h" //! [0] QString EchoPlugin::echo(const QString &message) { return message; } //! [0]

然后编译生成,我们需要 MyQtPlugin.dll MyQtPlugin.lib echointerface.h这三个文件

我们再新建一个工程 做一个界面 在这里插入图片描述 把刚才那三个文件复制到现在工程的目录下,把echointerface.h添加到工程里面(右键添加现有文件) 在这里插入图片描述 echowindow.h

#ifndef ECHOWINDOW_H #define ECHOWINDOW_H #include #include "echointerface.h" QT_BEGIN_NAMESPACE class QString; class QLineEdit; class QLabel; class QPushButton; class QGridLayout; namespace Ui { class echowindow; } QT_END_NAMESPACE class echowindow : public QWidget { Q_OBJECT public: echowindow(); ~echowindow(); private slots: void sendEcho(); private: void createGUI(); bool loadPlugin(); EchoInterface *echoInterface; QLineEdit *lineEdit; QLabel *label; QPushButton *button; QGridLayout *layout; }; #endif // ECHOWINDOW_H

echowindow.cpp

#include "echowindow.h" #include "ui_echowindow.h" #include "echowindow.h" #include #include #include #include #include #include #include #include //! [0] echowindow::echowindow() { createGUI(); setLayout(layout); setWindowTitle("Echo Plugin Example"); if (!loadPlugin()) { QMessageBox::information(this, "Error", "Could not load the plugin"); lineEdit->setEnabled(false); button->setEnabled(false); } } //! [0] //! [1] void echowindow::sendEcho() { QString text = echoInterface->echo(lineEdit->text()); label->setText(text); } //! [1] //! [2] void echowindow::createGUI() { lineEdit = new QLineEdit; label = new QLabel; label->setFrameStyle(QFrame::Box | QFrame::Plain); button = new QPushButton(tr("Send Message")); connect(lineEdit, &QLineEdit::editingFinished, this, &echowindow::sendEcho); connect(button, &QPushButton::clicked, this, &echowindow::sendEcho); layout = new QGridLayout; layout->addWidget(new QLabel(tr("Message:")), 0, 0); layout->addWidget(lineEdit, 0, 1); layout->addWidget(new QLabel(tr("Answer:")), 1, 0); layout->addWidget(label, 1, 1); layout->addWidget(button, 2, 1, Qt::AlignRight); layout->setSizeConstraint(QLayout::SetFixedSize); } //! [2] //! [3] bool echowindow::loadPlugin() { QDir pluginsDir(QCoreApplication::applicationDirPath()); #if defined(Q_OS_WIN) if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") pluginsDir.cdUp(); #elif defined(Q_OS_MAC) if (pluginsDir.dirName() == "MacOS") { pluginsDir.cdUp(); pluginsDir.cdUp(); pluginsDir.cdUp(); } #endif pluginsDir.cd("plugins"); const QStringList entries = pluginsDir.entryList(QDir::Files); for (const QString &fileName : entries) { QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); QObject *plugin = pluginLoader.instance(); if (plugin) { echoInterface = qobject_cast(plugin); if (echoInterface) return true; pluginLoader.unload(); } } return false; } echowindow::~echowindow() { }

main.cpp

#include "echowindow.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); echowindow w; w.show(); return a.exec(); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3